import datetime
from fastapi import APIRouter, HTTPException, Body
from pydantic import BaseModel
from typing import Optional, List

from utils.dbops import MariaDBConnector
import re
import requests

router = APIRouter(prefix="/im", tags=["IM机器人接口"])

class TextMsg(BaseModel):
    content: str

class ImageMsg(BaseModel):
    fileId: str
    height: int
    width: int
    groupId: str
    isMentioned: bool
    mentionedMobileList: List[str]

class FileMsg(BaseModel):
    fileId: str
    groupId: str
    isMentioned: bool
    mentionedMobileList: List[str]

class IMRequest(BaseModel):
    type: str
    callBackUrl: str
    callBackMethod: str
    phone: str
    groupId: str
    tenantId: int = 1
    robotId: str
    textMsg: Optional[TextMsg] = None
    imageMsg: Optional[ImageMsg] = None
    fileMsg: Optional[FileMsg] = None


@router.post("/robot/zw/{project_rowId}")
@router.post("/robot/{project_rowId}")
async def handle_im_robot(
    data: IMRequest = Body(..., embed=False),
    project_rowId: str = None
):
    """
    处理来自IM的机器人消息请求
    参数:
        request: IMRequest对象，包含IM发送的消息数据
    返回:
        处理结果或错误信息
    """
    # json格式输出data
    print(data.model_dump_json(indent=4))
    user = getUserInfoByPhone(data.phone)
    if not user:
        username = "Bot"
    else:
        username = user['name']

    db_config = {
        'host': 'mysql',
        'port': 3306,
        'user': 'root',
        'password': 'xj1983SH1216',
        'db': 'assistool_db'
    }
    
    connector = MariaDBConnector(**db_config)
    results = connector.execute_query(f"SELECT `_id`, `项目推进情况及问题`, `botCallback`, `botGroupId` FROM vProjectInfo WHERE row_id='{project_rowId}'")
    if not results:
        raise HTTPException(status_code=404, detail="Project not found")
    project = results[0]
    if project['botCallback'] != data.callBackUrl or project['botGroupId'] != data.groupId:
        print("update project bot callback:", data.callBackUrl)
        print("update project bot groupId:", data.groupId)
        connector.execute_update(f"UPDATE project SET botCallback='{data.callBackUrl}', botGroupId='{data.groupId}' WHERE row_id='{project_rowId}'")

    # 开始处理消息
    if data.type == "text":
        # 处理文本消息
        content = data.textMsg.content
        content = remove_mentions(content)
        if content.strip() == '':
            # 如果消息内容为空，则发送商机消息和项目进度消息
            # 发送商机消息
            opps = connector.execute_query(f"SELECT * FROM vOpportunityInfo WHERE projectId={project['_id']}")
            for opp in opps:
                msgContent = ""
                msgContent += f"商机编号：{opp['商机编号']}\r\n"
                msgContent += f"商机名称：{opp['商机名称']}\r\n"
                msgContent += f"客户名称：{opp['客户名称']}\r\n"
                msgContent += f"客户经理：{opp['客户经理']}\r\n"
                msgContent += f"解决方案经理：{opp['解决方案经理']}\r\n"
                msgContent += f"项目交付经理：{opp['项目经理']}\r\n"
                msgContent += f"商机第一责任人：{opp['商机第一责任人']}\r\n"
                msgContent += f"商机金额：{opp['商机金额']} 万元\r\n"
                msgContent += f"商机状态：{opp['商机状态']}\r\n"
                msgContent += f"商机产品：{opp['商机产品']}\r\n"
                msgContent += f"客户需求：{opp['客户需求']}\r\n"
                msgContent += f"--- 信息更新时间：{opp['mtime']} ---\r\n"
                postMessage(msgContent, data.groupId, data.callBackUrl)
                print("-"*5, "post message", "-"*5)
                print(msgContent)
                print("-"*5, "------------", "-"*5)

            # 发送项目进度消息
            postMessage(project['项目推进情况及问题'], data.groupId, data.callBackUrl)
            print("-"*5, "post message", "-"*5)
            print(project['项目推进情况及问题'])
            print("-"*5, "------------", "-"*5)
        elif content.startswith(":") or content.startswith("："):
            # 如果消息内容以冒号开头，则处理为进度
            statement = f"INSERT INTO progress (projectId, details, creator, workPhase, noProgress, updateDate) VALUES ({project['_id']}, '{content[1:].strip()}', '{username}', '售前', 0, '{datetime.date.today().strftime('%Y-%m-%d')}')"
            print("-"*5, "append progress", "-"*5)
            print(statement)
            print("-"*5, "---------------", "-"*5)
            connector.execute_update(statement)

        return {"success" : True, "message": "text message."}
    else:
        return {"success" : False, "message": "not text message."} 



def getUserInfoByPhone(phone: str) -> dict:
    """
    根据手机号获取用户信息的函数。

    参数:
        phone (str): 手机号。
        group (str): 群组名称。

    返回:
        dict: 用户信息字典。
    """
    # 配置数据库连接信息（替换为实际值）
    db_config = {
        'host': 'mysql',
        'port': 3306,
        'user': 'root',
        'password': 'xj1983SH1216',
        'db': 'assistool_db'
    }
    
    connector = MariaDBConnector(**db_config)

 
    # 示例查询
    results = connector.execute_query(f"SELECT * FROM assistool_db.sysuser WHERE phone = '{phone}';")
    # print("Query results:", results)
    return results[0] if (results and len(results) > 0) else None


def remove_mentions(text):
    # 匹配邮箱的正则表达式（简化版，覆盖常见格式）
    email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b'
    # 匹配@提及的正则表达式
    mention_pattern = r'@\S+'
    # 组合正则表达式，优先匹配邮箱
    combined_pattern = re.compile(f'({email_pattern})|({mention_pattern})')
    
    def replacer(match):
        # 如果是邮箱，保留原内容；否则替换提及为空
        return match.group(1) if match.group(1) else ''
    
    # 替换处理
    cleaned_text = combined_pattern.sub(replacer, text)
    # 合并多余空格
    cleaned_text = re.sub(r'\s+', ' ', cleaned_text).strip()
    return cleaned_text


def postMessage(msgContent: str, groupId: str, server_url: str):
    headers = {
        "content-type": "application/json"
    }
    payload = {
        "type": "text",
        "textMsg": {
            "content": msgContent,
            "isMentioned": False,
            "mentionType": 1,
            "mentionedMobileList": [],
            "groupId": groupId,
        }
    }

    response = requests.post(server_url, json=payload, headers=headers)
    print("消息已发送", payload)
    response.raise_for_status()

    return response


if __name__ == '__main__':
    ss = getUserInfoByPhone("18918588610")
    print(ss)